package xp2p.inter.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import xp2p.inter.msg.FinishedMessage;
import xp2p.inter.msg.Message;
import xp2p.inter.msg.MessageRequest;
import xp2p.trashes.BytesConverter;

public class Client
{
	private int _port;
	private Socket _socket;
	private boolean closed = false;
	
	public Client(int port)
	{
		_port = port;
	}
	
	public void connect() throws UnknownHostException, IOException
	{
		_socket = new Socket(InetAddress.getLocalHost(), _port);		
	}
	
	public void send(Serializable message) throws IOException, ClassNotFoundException
	{
		OutputStream out = _socket.getOutputStream();
		ObjectOutputStream outobj = new ObjectOutputStream(out);
		outobj.writeObject(message);
	
		InputStream in = _socket.getInputStream();
		ObjectInputStream inobj = new ObjectInputStream(in);
		Object response = inobj.readObject();
		HandleResponse(response);
	}	
	
	public Serializable request(Serializable message) throws IOException, ClassNotFoundException
	{
		OutputStream out = _socket.getOutputStream();
		ObjectOutputStream outobj = new ObjectOutputStream(out);
		outobj.writeObject(message);
		
		InputStream in = _socket.getInputStream();
		ObjectInputStream inobj = new ObjectInputStream(in);
		Object response = inobj.readObject();
		return HandleResponse(response);
	}
	
	private Serializable HandleResponse(Object response) throws IOException, ClassNotFoundException
	{
		if (response.getClass().equals(FinishedMessage.class))			
		{			
			close();
		}
		if (response.getClass().equals(Message.class))			
		{			
			return BytesConverter.bytesToObj(((Message)response).Inner);
		}
		return null;
	}
	
	public boolean wasClosed()
	{
		return closed;
	}

	public void close()
	{
		try
		{
			if (closed)
			{
				return;
			}
			closed = true;
			_socket.close();			
		} catch (IOException e)
		{			
			e.printStackTrace();
		}
		finally
		{
			_socket = null;
		}
	}
}
